<template>
  <div></div>
</template>

<script>
import * as THREE from 'three'
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min'

export default {
  name: 'ThirteenEight',
  data() {
    return {
      torus: null,                   // 圆环对象
    }
  },
  mounted() {
    this.initScene();
    this.initCamera();
    this.initRenderer();
    this.addTorusGeometry(3, 1, 8, 8, Math.PI * 2);
    this.addOrbitControls();
    this.animation();
    this.initControl();
  },
  methods: {
    // 初始化场景
    initScene() {
      this.scene = new THREE.Scene();
    },
    // 初始化相机
    initCamera() {
      // 创建一个相机 视点
      this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
      // 设置相机的位置
      this.camera.position.x = 0;
      this.camera.position.y = 0;
      this.camera.position.z = 8;
      this.camera.lookAt(0, 0, 0);
    },
    // 初始化渲染器
    initRenderer() {
      // 创建一个渲染器
      this.renderer = new THREE.WebGLRenderer();
      // 设置渲染器尺寸
      this.renderer.setSize(window.innerWidth, window.innerHeight);
      document.body.appendChild(this.renderer.domElement);
    },
    // 添加一个圆环
    addTorusGeometry(radius = 1, tube = 0.4, radialSegments = 12, tubularSegments = 48, arc = Math.PI * 2) {
      const torusGeometry = new THREE.TorusGeometry(radius, tube, radialSegments, tubularSegments, arc);
      const torusMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
      torusMaterial.side = THREE.DoubleSide;
      torusMaterial.wireframe = true;
      this.torus = new THREE.Mesh(torusGeometry, torusMaterial);
      this.scene.add(this.torus);
    },
    // 添加轨道控制器
    addOrbitControls() {
      this.orbitControls = new OrbitControls(this.camera, this.renderer.domElement);
      // 设置带阻尼的惯性
      this.orbitControls.enableDamping = true;
      // 设置阻尼系数
      this.orbitControls.dampingFactor = 0.05;
    },
    // 动画函数
    animation() {
      this.orbitControls.update();
      // 渲染
      this.renderer.render(this.scene, this.camera);
      requestAnimationFrame(this.animation);
    },
    // 初始化lil.gui调试工具
    initControl() {
      const gui = new GUI();

      const params = {
        radius: this.torus.geometry.parameters.radius,
        tube: this.torus.geometry.parameters.tube,
        radialSegments: this.torus.geometry.parameters.radialSegments,
        tubularSegments : this.torus.geometry.parameters.tubularSegments ,
        arc: this.torus.geometry.parameters.arc,
      }

      let folder = gui.addFolder('圆环属性');
      folder.add(params, 'radius', -3, 10).step(0.1).name('radius-环面半径').onChange(radius => {
        params.radius = radius;
        this.scene.remove(this.torus);
        this.addTorusGeometry(params.radius, params.tube, params.radialSegments, params.tubularSegments, params.arc);
      });
      folder.add(params, 'tube', -3, 10).step(0.1).name('tube-管道半径').onChange(tube => {
        params.tube = tube;
        this.scene.remove(this.torus);
        this.addTorusGeometry(params.radius, params.tube, params.radialSegments, params.tubularSegments, params.arc);
      });
      folder.add(params, 'radialSegments', 0, 50).step(1).name('radialSegments-横截面分段数').onChange(radialSegments => {
        params.radialSegments = radialSegments;
        this.scene.remove(this.torus);
        this.addTorusGeometry(params.radius, params.tube, params.radialSegments, params.tubularSegments, params.arc);
      });
      folder.add(params, 'tubularSegments', 3, 50).step(1).name('tubularSegments-管道分段数').onChange(tubularSegments => {
        params.tubularSegments = tubularSegments;
        this.scene.remove(this.torus);
        this.addTorusGeometry(params.radius, params.tube, params.radialSegments, params.tubularSegments, params.arc);
      });
      folder.add(params, 'arc', 0, 2 * Math.PI).step(0.1).name('arc-圆心角').onChange(arc => {
        params.arc = arc;
        this.scene.remove(this.torus);
        this.addTorusGeometry(params.radius, params.tube, params.radialSegments, params.tubularSegments, params.arc);
      });
    }
  }
}
</script>

<style scoped>

</style>
